package upmc.fr.android.rss.actions;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import upmc.fr.android.rss.RSSArticle;
import upmc.fr.android.rss.RSSCategory;
import upmc.fr.android.rss.RSSFlow;
import upmc.fr.android.rss.parser.IRSSFlowReader;
import upmc.fr.android.rss.parser.RSSFlowReader;
import upmc.fr.android.rss.parser.RSSReadingException;
import upmc.fr.android.rss.persistence.FilePersistence;

public class UserActions implements IUserActions 
{
	private IRSSFlowReader reader = new RSSFlowReader();	
	private List<RSSCategory> categories;
	
	public UserActions()
	{
		try 
		{
			categories = FilePersistence.load();
		}
		catch (Exception e) 
		{		
			categories = new LinkedList<RSSCategory>();
		}
	}
	
	@Override
	public void addCategory(RSSCategory category)
	{
		this.categories.add(category);
	}

	@Override
	public void removeCategory(RSSCategory category) 
	{
		this.categories.remove(category);
	}

	@Override
	public void addRSSFlow(RSSCategory category, String url) throws RSSReadingException 
	{
		RSSFlow flow = reader.read(url);
		int index = this.categories.indexOf(category);
		this.categories.get(index).addFlow(flow);
	}

	@Override
	public void removeRSSFlow(RSSCategory category, RSSFlow flow) 
	{
		int index = this.categories.indexOf(category);
		this.categories.get(index).removeFlow(flow);
	}

	@Override
	public List<RSSFlow> getFlows(RSSCategory category) 
	{
		return category.getFlows();
	}
	
	@Override
	public List<RSSFlow> getFlows(RSSCategory category, Comparator<RSSFlow> comparator) 
	{
		List<RSSFlow> result = getFlows(category);
		Collections.sort(result, comparator);
		return result;
	}	

	@Override
	public List<RSSArticle> getArticles(RSSFlow flow, Comparator<RSSArticle> comparator) 
	{
		List<RSSArticle> result = flow.getArticles();
		Collections.sort(result, comparator);
		return result;
	}	
	
	@Override
	public List<RSSArticle> getArticles()
	{
		List<RSSArticle> result = new LinkedList<RSSArticle>();
		for(RSSCategory category : categories)
		{
			for(RSSFlow flow : category.getFlows())
				result.addAll(flow.getArticles());
		}
		return result;
	}

	@Override
	public List<RSSArticle> getArticles(Comparator<RSSArticle> comparator)
	{
		List<RSSArticle> result = new LinkedList<RSSArticle>();
		for(RSSCategory category : categories)
		{
			for(RSSFlow flow : category.getFlows())
				result.addAll(flow.getArticles());
		}
		Collections.sort(result, comparator);
		return result;
	}

	@Override
	public void exit() 
	{
		try 
		{
			FilePersistence.persist(categories);
		}
		catch (IOException e) 
		{		
			e.printStackTrace();
		}
	}

	@Override
	public void update() throws RSSReadingException
	{		
		List<RSSCategory> copyCategories = new LinkedList<RSSCategory>();
		Collections.copy(copyCategories, categories);
		
		for(int i=0; i<categories.size(); i++)
		{
			for(RSSFlow flow : categories.get(i).getFlows())
				copyCategories.get(i).addFlow(reader.read(flow.getUrl()));			
		}
		
		categories = copyCategories;
	}

	@Override
	public RSSCategory[] getCategories() 
	{
		RSSCategory[] result = new RSSCategory[categories.size()];
		for(int i=0; i<categories.size(); i++)
			result[i] = categories.get(i);
		return result;
	}

	@Override
	public List<RSSArticle> getArticles(RSSCategory category, Comparator<RSSArticle> comparator) 
	{
		List<RSSArticle> result = new LinkedList<RSSArticle>();
		for(RSSFlow flow : category.getFlows())
			result.addAll(flow.getArticles());
		Collections.sort(result, comparator);
		return result;
	}	
}
